﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Tuxedo.Link.Passes
{
	internal class Flatten : Pass
	{
		public override void Apply(PassContext context, Class[] classes)
		{
			Dictionary<string, bool> potentialNamespaces = new Dictionary<string, bool>();

			foreach (Class clazz in classes)
			{
				string name = clazz.FullyQualifiedName;
				if (context.ClassByFullName.ContainsKey(name))
				{
					throw new Exception("Two classes named: " + name);
				}

				context.ClassByFullName[name] = clazz;

				// everything in the full path is considered a potential namespace name at first.
				foreach (string possibleNamespace in this.GeneratePossibleNamespaces(name))
				{
					potentialNamespaces[possibleNamespace] = true;
				}
			}

			// Now that we know what all the classes are, remove the namespaces that are class names.
			List<string> namespaces = new List<string>(potentialNamespaces.Keys);
			int i = 0;
			while (i < namespaces.Count)
			{
				if (context.ClassByFullName.ContainsKey(namespaces[i]))
				{
					namespaces.RemoveAt(i);
				}
				else
				{
					++i;
				}
			}

			context.Namespaces = new HashSet<string>(namespaces);

			// TODO: populate class parent property. Verify there are no classes that collide with namespaces.
		}

		private ICollection<string> GeneratePossibleNamespaces(string className)
		{
			List<string> output = new List<string>();
			string[] parts = className.Split('.');
			if (parts.Length > 1)
			{
				string name = parts[0];
				output.Add(name);
				for (int i = 1; i < parts.Length - 1; ++i)
				{
					name += "." + parts[i];
					output.Add(name);
				}
			}
			return output;
		}
	}
}
